# -*- coding: utf-8 -*-
#  自定义普通的tableModel
# @Time    ： 2022/2/14  10:39
# @Auther  ： 徐良
# File     :  tableModel.py
from PySide6.QtCore import QAbstractTableModel, QModelIndex, Qt, Signal
from PySide6.QtCore import Qt, QModelIndex, Signal
from PySide6.QtGui import QColor

from share.dataFactory import DataFactory
from share.baseFunction import getInstanceType
from baseClass.baseModel import BaseModel
from baseClass.baseRecord import BaseRecord
from share.modelFunction import getModel
from utils.tableToList import ListFromModel


class TableModelMap(QAbstractTableModel):
    """
    可编辑表格model
    """
    dataChangedSignal = Signal(BaseModel, QModelIndex)
    def __init__(self, args):

        super(TableModelMap, self).__init__()
        self.dirty = False
        self.listDel = set()
        self.listUpdate = set()  # 保存更改记录的hash值
        self.insertFlag = 0

        self.model = None
        self.ROB = 0  # 红蓝字， 0为蓝字，1为红字

        self.pdic = args
        self.sql = args['sql']
        self.baseDbType = args['baseDbType']
        self.fieldList = args['fieldList']
        self.fieldNameList = args['fieldNameList']
        self.alignList = args['alignList']
        self._data = []
        self._headers = self.fieldNameList
        self.fieldValList = []

        self._records = []
        self._record = []

        if 'baseDbType' in args:
            self.baseDbType = args['baseDbType']
        else:
            self.baseDbType = None

        if 'fieldNameList' in args:
            self.fieldNameList = args['fieldNameList']
        if 'sql' in args:
            self.sSql = args['sql']
        else:
            self.sSql = ''

        if 'model' in args and args['model'] is not None:
            self.model = args['model']


        if 'alignList' in args:
            self.alignList = args['alignList']
        else:
            self.alignList = []

        if len(self.fieldList) == 0:
            listFromModel = ListFromModel(self.model)
            self.fieldList = listFromModel.getFieldList()

        self.dirty = False
        if len(self.fieldNameList) > 0:
            column = len(self.fieldNameList)
        else:
            column = self.model.columnCount()

        for i in range(0, column):
            self.fieldValList.append('')

        self.loadDataFromModel()

    def flags(self, index):
        if not index.isValid():
            return Qt.ItemIsSelectable | Qt.ItemIsEditable | Qt.ItemIsEnabled

        return Qt.ItemFlags(QAbstractTableModel.flags(self, index) | Qt.ItemIsEditable)

    def record(self, num):
        if 0 <= num < self.rowCount():
            return self._records[num]
        else:
            return None

    def rowCount(self, parent=QModelIndex()):
        return len(self._data)

    def columnCount(self, parent=QModelIndex()):
        # return len(self._data[0]) if self._data else 0
        return len(self._headers)

    def removeRows(self, position, rows=1, index=QModelIndex()):
        self.beginRemoveRows(QModelIndex(), position, position + rows - 1)
        self._records = (self._records[:position] + self._records[position + rows:])
        del self._data[position]
        self.endRemoveRows()
        self.dirty = True
        return True

    def insertRows(self, position, rows=1, index=QModelIndex()):
        """
        插入行
        :param position: 插入起始行
        :param rows: 插入行数量
        :param index:
        :return:
        """
        self.beginInsertRows(QModelIndex(), position, position + rows - 1)
        for row in range(rows):
            self._records.insert(position + row, BaseRecord(self.fieldList, self.getDefaultRecordList()))
            self._data.insert(position + row, self.getDefaultDataList())
        self.endInsertRows()
        self.dirty = True
        return True

    def headerData(self, section, orientation, role=Qt.DisplayRole):
        if role == Qt.DisplayRole:
            if orientation == Qt.Horizontal:
                return self._headers[section]
            elif orientation == Qt.Vertical:
                return str(section + 1)
        return None


    def data(self, index, role=Qt.DisplayRole):

        row = index.row()
        col = index.column()
        if (not index.isValid()) or not (0 <= row <= len(self._data)):
            return None

        if role == Qt.DisplayRole or role == Qt.EditRole:
            return self._data[row][col]

    def setData(self, index, value, role=Qt.EditRole):
        before = self.data(index)
        row = index.row()
        col = index.column()
        if index.isValid() and 0 <= index.row() <= len(self._records):
            # 特别主要，加上self.beginResetModel() self.endResetModel()，会导致QDataWidgetMapper()
            # 与QTableView数据不联动
            # self.beginResetModel()
            self._data[row][col] = value
            record = self._records[index.row()]
            column = index.column()
            if getInstanceType(value) == 'int':
                expression = 'record.' + self.fieldList[column].lower() + ' = int(value)'
            else:
                expression = 'record.' + self.fieldList[column].lower() + ' = str(value)'  # 界面的值赋给record对象
            exec(expression)
            self.dataChanged.emit(index, index, [role])
            if index.column() != 0 and before != value:
                self.dirty = True
                self.dataChangedSignal.emit(self, index)
            # self.endResetModel()
            return True

        return False

    def setROB(self, value):
        """
        设置红蓝字
        :param value:
        """
        if self.ROB != value:
            self.ROB = value
            # 发射信号，通知视图数据发生变化, 此处应该发红字变化信号，等待修正
            # self.dataChangedSignal.emit(self.index(0, 0), self.index(self.rowCount() - 1, self.columnCount() - 1))

    def getColForField(self, field_name):
        """
        获取字段名所处的列
        :return:
        """
        if field_name in self.fieldList:
            index = self.fieldList.index(field_name)
            return index
        else:
            return -1

    def loadDataFromModel(self):
        # 创建数据库连接
        if self.model is None:
            model = getModel(self.sql, self.baseDbType)
        else:
            model = self.model

        # 将查询结果转换为二维列表
        self._data = []
        for row in range(0, model.rowCount()):
            vList = []
            rvList = []  # 用于存放记录形式
            for fname in self.fieldList:
                val = model.record(row).value(fname)
                vList.append(val)

                # 记录形式
                if getInstanceType(val) == 'QDate':
                    val = val.toString("yyyy-MM-dd")
                elif getInstanceType(val) == 'QDateTime':
                    val = val.toString("yyyy-MM-dd hh:mm:ss")

                rvList.append(val)

            self._data.append(vList)

            r = BaseRecord(self.fieldList, rvList)
            self._records.append(r)

    def getDefaultDataList(self):
        """
        增加记录时，默认的_data列表中的元素（列表格式）
        :return:
        """
        return [None for _ in self.fieldList]

    def getDefaultRecordList(self):
        """
        增加记录时，默认的_records列表中的记录（record格式）
        :return:
        """
        return ['' for _ in self.fieldList]

